package priv.xakml.demo.boot18mybatisplus.controller;

import cn.hutool.core.lang.Tuple;
import cn.hutool.core.net.NetUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lhx
 * @date 2022-05-28 14:20
 **/
public class IPUtils {

    /**
     * 从Ip138上查询指定IP的物理归属地范围
     * @param ip
     * @return
     */
    public static List<IpInfo> getIPGeolocationFromIP138(String ip) {
        List<IpInfo> geo_location = new ArrayList<>();;
        String baseUrl = "https://www.ip138.com/iplookup.asp?ip="+ip+"&action=2";

        Map<String,Object> params = new HashMap<>();

        try {
            HttpResponse httpResponse = HttpRequest.get(baseUrl)
                    .header("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
                    .header("Accept-Encoding","gzip, deflate, br")
                    .header("Accept-Language","zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                    .header("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36 Edg/101.0.1210.39")
                    .execute();
            int httpStatus = httpResponse.getStatus();
//        System.out.println(httpStatus);
            String content = httpResponse.body();
            if(content.length() > 0){
                Document document = Jsoup.parse(content);
                Elements element = document.selectXpath("/html/head/script[2]");
                if(element != null){
                    String js_content = element.html();
                    if(js_content != null){
//                    System.out.println(js_content);

                        BufferedReader bufferedReader = new BufferedReader(new StringReader(js_content));
                        String line = null;
                        do {
                            line = bufferedReader.readLine();
                            if(line != null)
                                line = line.replace("\t","");
                            if(line != null && line.startsWith("var ip_result")){
                                String[] json_and_varname = line.split("=");
                                if(json_and_varname != null && json_and_varname.length == 2)
                                {
                                    String ip_json = null;
                                    if (json_and_varname[1].endsWith(";"))
                                    {
                                        StringBuilder stringBuilder = new StringBuilder(json_and_varname[1]);
                                        String original_json = stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString();
                                        List<Tuple> tupleList = parseIp138ResponseJs(original_json);
                                        if(null != tupleList && tupleList.size() > 0){
                                            tupleList.forEach(obj -> {
                                                IpInfo ipInfo = new IpInfo();
                                                ipInfo.setIp(ip);
                                                ipInfo.setIpLongFormat(NetUtil.ipv4ToLong(ip));
                                                ipInfo.setLocationStart(obj.get(0));
                                                ipInfo.setLocationEnd(obj.get(1));
                                                ipInfo.setGeoLocation(obj.get(2));
                                                geo_location.add(ipInfo);
                                            });
                                        }
                                    }
//                                System.out.println(json_and_varname[1]);

                                }
                                break;
                            }
                        }while (line != null);
                    }
                    else
                        System.out.println("js content is null");
                }
            }
        }catch (Exception exception){
            System.out.println(exception.getMessage());
        }
        return geo_location;
    }


    private static List<Tuple> parseIp138ResponseJs(String source_original){
        List<Tuple> list = new ArrayList<>();
        JSONObject jsonObject = JSONUtil.parseObj(source_original);
        String location = jsonObject.getStr("ASN归属地");
        JSONArray ip_c_list = jsonObject.getJSONArray("ip_c_list");
        if(ip_c_list != null && ip_c_list.size() > 0) {
            for (int i = 0; i < ip_c_list.size(); i++) {
                JSONObject jsonObject1 = ip_c_list.getJSONObject(i);
                if (jsonObject1 != null) {
                    Long begin = jsonObject1.getLong("begin");
                    Long end = jsonObject1.getLong("end");
                    Tuple tuple = new Tuple(begin, end, location);
                    list.add(tuple);
//                System.out.println("begin:" +begin);
//                System.out.println("end:" +end);
                }
            }
        }
//        System.out.println(ip_c_list);
        return list;
    }

}
